const fs = require('fs');
const path = require('path');

//方式1
async function method1() {
  const from = path.resolve(__dirname, './temp/abc.txt');
  const to = path.resolve(__dirname, './temp/abc2.txt');
  console.time('方式1');
  const content = await fs.promises.readFile(from);
  await fs.promises.writeFile(to, content);
  console.timeEnd('方式1');
  console.log('复制完成');
}

//方式2
async function method2() {
  const from = path.resolve(__dirname, './temp/abc.txt');
  const to = path.resolve(__dirname, './temp/abc2.txt');
  console.time('方式2');

  const rs = fs.createReadStream(from);
  const ws = fs.createWriteStream(to);
  rs.on('data', (chunk) => {
    //读到一部分数据
    const flag = ws.write(chunk);
    if (!flag) {
      //表示下一次写入，会造成背压
      rs.pause(); //暂停读取
    }
  });

  ws.on('drain', () => {
    //可以继续写了
    rs.resume();
  });

  rs.on('close', () => {
    //写完了
    ws.end(); //完毕写入流
    console.timeEnd('方式2');
    console.log('复制完成');
  });
}

// method2();

async function method3() {
  const filename = path.resolve(__dirname, './abc.txt');
  const to = path.resolve(__dirname, './temp/abc1.txt');
  const rs = fs.createReadStream(filename, {
    encoding: 'utf-8', // 为null highWaterMark 表示 多少字节  utf-8 时 highWaterMark表示 多少个字符
    highWaterMark: 1, // 每次读取的字节数 或自符数  1个汉字占三个字节
    autoClose: true, // 文件读完 自动关闭 默认true
    // start: 20, // 开始位置
    // end: 10, // 结束位置
  }); // 创建可读流

  const ws = fs.createWriteStream(to, {
    flags: 'a', // 写文件的方式 默认r  a追加 w覆盖
    encoding: 'utf-8',
    highWaterMark: 1, // 一次最多写多少 字节 或字符
    // autoClose: true,
  }); // 创建可写流
  rs.on('data', (chunk) => {
    console.log(chunk, 'chunk');
    // 磁盘处理速度慢
    const stat = ws.write(chunk); // 写入 传字符串 或者 buffer
    // 返回true 代表 没有塞满 通道 ， 返回false 代表满了
    // 写入 和 磁盘 之前有个通道  通道的值 highWaterMark 可以设置
    if (!stat) {
      // 如果满了 还继续写的话 就会产生背压  会存在内存中
      // 为了 不占太多内存 通道满了 就要暂停读取
      rs.pause();
      // ws.end() // 手动关闭
    }
    // 文件读完 自动关闭
    // rs.close(); // 手动关闭
    // rs.pause(); // 暂停读取  有对应的事件
    // rs.resume(); // 继续读取
  });

  ws.on('drain', () => {
    // drain 表示 通道 清空 了 会触发
    rs.resume();
  });

  // ws.on('open', () => {
  //   console.log('open');
  // });

  // ws.on('close', () => {
  //   console.log('close');
  // });

  // rs.on('error', (chunk) => {
  //   console.log(chunk, 'error');
  // });

  // rs.on('open', (chunk) => {
  //   console.log(chunk, 'open');
  // });

  // rs.on('end', (chunk) => {
  //   console.log(chunk, 'end');
  // });
  // rs.on('pause', (chunk) => {
  //   console.log(chunk, 'pause');
  // });

  // rs.on('resume', (chunk) => {
  //   console.log(chunk, 'resume');
  // });
}
method3();
